package com.daisuxia.back.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.daisuxia.back.service.IBackModuleService;
import com.daisuxia.back.utils.DwzResult;
import com.daisuxia.back.utils.ServiceResult;
import com.daisuxia.back.utils.SpringUtils;
import com.daisuxia.back.utils.SysCacheUtils;
import com.daisuxia.risk.pojo.RiskManageRule;
import com.daisuxia.risk.service.IBqsService;
import com.daisuxia.risk.service.IJxlMgService;
import com.daisuxia.risk.service.IJxlService;
import com.daisuxia.risk.service.IJyzxService;
import com.daisuxia.risk.service.IRiskManageRuleService;
import com.daisuxia.risk.service.IRiskTaskService;
import com.daisuxia.risk.service.ITdService;
import com.daisuxia.risk.service.IYxService;
import com.daisuxia.risk.service.IZmxyService;
import com.daisuxia.risk.utils.ConstantRisk;
import com.daisuxia.risk.utils.FormulaUtil;
import com.daisuxia.risk.utils.RuleChart;
import com.daisuxia.web.controller.BaseController;
import com.daisuxia.web.listener.IndexInit;
import com.daisuxia.web.util.JSONUtil;

@Controller
@RequestMapping("risk/")
public class RiskManageController extends BaseController {
	Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private IRiskManageRuleService riskManageRuleService;
	@Autowired
	private IZmxyService zmxyService;
	@Autowired
	private ITdService tdService;
	@Autowired
	private IBqsService bqsService;
	@Autowired
	private IJyzxService jyzxService;
	@Autowired
	private IJxlMgService jxlMgService;
	@Autowired
	private IJxlService jxlService;
	@Autowired
	private IRiskTaskService riskTaskService;
	@Autowired
	private IBackModuleService backModuleService;
	@Autowired
	private IYxService yxService;

	@RequestMapping("test")
	public void test(HttpServletRequest request, HttpServletResponse response,
			Model model) {
		HashMap<String, Object> params = this.getParametersO(request);
		// ServiceResult serviceResult = zmxyService.getOpenId(params);
		// ServiceResult serviceResult = zmxyService.getURL(params, request);
		// ServiceResult serviceResult = zmxyService.getCreditWatchList(params);
		// ServiceResult serviceResult = tdService.getReport(params);
		// ServiceResult serviceResult = tdService.queryReport(params);
		// ServiceResult serviceResult = bqsService.getRisk(params);
		// ServiceResult serviceResult = jyzxService.getBorrow(params);
		// ServiceResult serviceResult = jxlMgService.getDetail(params);
		// ServiceResult serviceResult = jxlService.getToken(params);
//		ServiceResult serviceResult = yxService.sendYx(params);
//		SpringUtils.renderJson(response, serviceResult);
		// riskTaskService.findJxlReport();
		 riskTaskService.updateAnalysis();
		// riskTaskService.updateEd();
	}
	/**
	 *分页查询
	 * 
	 * @param request
	 * @param response
	 * @param model
	 * @return
	 */
	@RequestMapping("findList")
	public String findList(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		HashMap<String, Object> params = this.getParametersO(request);
		String errorMsg = null;
		try {
			model.addAttribute("params", params);
			model.addAttribute("pm", riskManageRuleService.findPage(params));
		} catch (Exception e) {
			errorMsg = "服务器异常。请稍后重试！";
			logger.error("findList error", e);
		}
		model.addAttribute(MESSAGE, errorMsg);
		return "risk/ruleList";
	}

	public ServiceResult checkCode(String formula, String self) {
		ServiceResult serviceResult = new ServiceResult("500", "变量校验出现异常");
		try {
			String[] array = formula.split(ConstantRisk.REGEX);
			Set<String> set = new HashSet<String>(Arrays.asList(array));
			Map<String, RiskManageRule> allRule = SysCacheUtils.getAllRule();
			boolean flag = true;
			for (String code : set) {
				if (StringUtils.isNotBlank(code)) {
					code = code.replaceAll(" ", "");
					if (code.startsWith(ConstantRisk.RETURN_CHAR)) {
						if (!code.endsWith(ConstantRisk.RETURN_CHAR)) {
							serviceResult.setMsg(code + "未包含结束符号"
									+ ConstantRisk.RETURN_CHAR);
							break;
						}
					} else if (code.endsWith(ConstantRisk.RETURN_CHAR)) {
						if (!code.startsWith(ConstantRisk.RETURN_CHAR)) {
							serviceResult.setMsg(code + "未包含开始符号"
									+ ConstantRisk.RETURN_CHAR);
							break;
						}
					} else {
						if (!code.matches(ConstantRisk.REGEX_NUM)) {
							if (StringUtils.isNotBlank(self)
									&& self.equals(code)) {
								flag = false;
								serviceResult
										.setMsg("表达式中不能包含当前所编辑的ID号" + code);
								break;
							} else {
								if (!allRule.containsKey(code)) {
									flag = false;
									serviceResult.setMsg("ID号" + code + "不存在");
									break;
								}
							}
						}
					}
				}
			}
			if (flag) {
				serviceResult = new ServiceResult(ServiceResult.SUCCESS, "校验通过");
			}
		} catch (Exception e) {
			logger.error("checkCode", e);
		}
		return serviceResult;
	}

	/**
	 * 添加规则
	 * 
	 * @param request
	 * @param response
	 * @param model
	 */
	@RequestMapping(value = "/save")
	public String save(HttpServletRequest request,
			HttpServletResponse response, Model model,
			RiskManageRule riskManageRule) {
		HashMap<String, Object> params = this.getParametersO(request);
		String url = null;
		String erroMsg = "";
		boolean flag = false;
		try {
			String type = params.get("type") + "";
			if ("toJsp".equals(type)) {
				url = "risk/saveUpdate";
			} else {
				boolean allow = true;
				ServiceResult serviceResult = null;
				riskManageRule.setFormulaShow(riskManageRule.getFormula());
				if (riskManageRule.getRuleType().intValue() == RiskManageRule.RULE_EXTEND) {
					FormulaUtil.checkFormula(riskManageRule.getFormula());
					serviceResult = checkCode(riskManageRule.getFormula(), null);
				}
				if (serviceResult != null && serviceResult.isFail()) {
					erroMsg = serviceResult.getMsg();
					allow = false;
				}
				if (allow) {
					riskManageRuleService.insert(riskManageRule);
					flag = true;
					new IndexInit().updateRiskCache();
					String localhostBack = request.getServerName() + ":"
							+ request.getServerPort();
					backModuleService.updateCacheOthers(localhostBack);// 刷新其它后台
				}
				SpringUtils.renderDwzResult(response, flag, erroMsg,
						DwzResult.CALLBACK_CLOSECURRENT, params.get("parentId")
								+ "");
			}
			params.put("url", "save");
			model.addAttribute("params", params);
		} catch (Exception e) {
			if (url == null) {
				String msg = e.getLocalizedMessage();
				String key = "FormulaUtil.calFormula@";
				int index = msg.indexOf(key);
				if (index >= 0) {
					erroMsg = "规则错误，请检查！";
				}
				SpringUtils.renderDwzResult(response, false, "操作失败" + erroMsg,
						DwzResult.CALLBACK_CLOSECURRENT, params.get("parentId")
								+ "");
			} else {
				erroMsg = "服务器异常，请稍后重试！";
			}
			logger.error("save error", e);
		} finally {
			model.addAttribute(MESSAGE, erroMsg);
		}
		return url;
	}

	/**
	 * 更新规则
	 * 
	 * @param request
	 * @param response
	 * @param model
	 */
	@RequestMapping(value = "/update")
	public String update(HttpServletRequest request,
			HttpServletResponse response, Model model,
			RiskManageRule riskManageRule) {
		HashMap<String, Object> params = this.getParametersO(request);
		String url = null;
		String erroMsg = null;
		boolean flag = false;
		try {
			String type = params.get("type") + "";
			if ("toJsp".equals(type)) {
				Integer id = Integer.valueOf(params.get("id") + "");
				RiskManageRule riskManageRule2 = riskManageRuleService
						.findById(id);
				model.addAttribute("rule", riskManageRule2);
				url = "risk/saveUpdate";
			} else {
				boolean allow = true;
				ServiceResult serviceResult = null;
				riskManageRule.setFormulaShow(riskManageRule.getFormula());
				if (riskManageRule.getRuleType().intValue() == RiskManageRule.RULE_EXTEND) {
					FormulaUtil.checkFormula(riskManageRule.getFormula());
					serviceResult = checkCode(riskManageRule.getFormula(),
							ConstantRisk.RULE_PREFIX + riskManageRule.getId());
				}
				if (serviceResult != null && serviceResult.isFail()) {
					erroMsg = serviceResult.getMsg();
					allow = false;
				}
				if (allow) {
					riskManageRuleService.update(riskManageRule);
					flag = true;
					new IndexInit().updateRiskCache();
					String localhostBack = request.getServerName() + ":"
							+ request.getServerPort();
					backModuleService.updateCacheOthers(localhostBack);// 刷新其它后台
				}
				SpringUtils.renderDwzResult(response, flag, erroMsg,
						DwzResult.CALLBACK_CLOSECURRENT, params.get("parentId")
								+ "");
			}
			params.put("url", "update");
			model.addAttribute("params", params);
		} catch (Exception e) {
			if (url == null) {
				String msg = e.getLocalizedMessage();
				String key = "FormulaUtil.calFormula@";
				int index = msg.indexOf(key);
				if (index >= 0) {
					erroMsg = "规则错误，请检查！";
				}
				SpringUtils.renderDwzResult(response, false, "操作失败" + erroMsg,
						DwzResult.CALLBACK_CLOSECURRENT, params.get("parentId")
								+ "");
			} else {
				erroMsg = "服务器异常，请稍后重试！";
			}
			logger.error("update error", e);
		} finally {
			model.addAttribute(MESSAGE, erroMsg);
		}
		return url;
	}

	/*** echart树开始 **/
	@RequestMapping(value = "/viewTree")
	public String viewTree(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		String url = null;
		HashMap<String, Object> params = this.getParametersO(request);
		String erroMsg = "";
		try {
			String type = params.get("type") + "";
			if ("toJsp".equals(type)) {
				Integer id = Integer.valueOf(params.get("id") + "");
				RiskManageRule riskManageRule2 = riskManageRuleService
						.findById(id);
				model.addAttribute("rule", riskManageRule2);
				RuleChart ruleChart = new RuleChart(ConstantRisk.RULE_PREFIX
						+ riskManageRule2.getId()
						+ riskManageRule2.getRuleName(), riskManageRule2
						.getFormulaShow().replaceAll("\r\n", "<br>"));
				List<RiskManageRule> list = Arrays.asList(riskManageRule2);
				List<RuleChart> list2 = Arrays.asList(ruleChart);
				createTree(list, list2);
				String data = JSONUtil.beanListToJson(list2);
//				System.out.println(data);
				model.addAttribute("data", data);
				url = "risk/tree";
			}
		} catch (Exception e) {
			logger.error("viewTree", e);
		}
		return url;
	}

	public void createTree(List<RiskManageRule> list, List<RuleChart> list2) {
		Map<String, RiskManageRule> map = SysCacheUtils.getAllRule();
		for (int j = 0; j < list.size(); j++) {
			RiskManageRule rule = list.get(j);
			RuleChart ruleChart = list2.get(j);
			String id = ConstantRisk.RULE_PREFIX + rule.getId();
			if (rule.getRuleType().intValue() == RiskManageRule.RULE_BASE
					.intValue()) {

			} else if (rule.getRuleType().intValue() == RiskManageRule.RULE_EXTEND
					.intValue()) {
				String[] array = rule.getFormula().split(ConstantRisk.REGEX);
				List<RiskManageRule> child = new ArrayList<RiskManageRule>();
				List<RuleChart> children = new ArrayList<RuleChart>();
				List<String> hasCode = new ArrayList<String>();
				for (int i = 0; i < array.length; i++) {
					if (StringUtils.isNotBlank(array[i])) {
						String unit = array[i].trim();
						if (hasCode.contains(unit)) {
							continue;
						}
						hasCode.add(unit);
						RiskManageRule rule2 = map.get(unit);
						if (rule2 != null) {
							RuleChart ruleChart2 = new RuleChart(
									ConstantRisk.RULE_PREFIX + rule2.getId()
											+ rule2.getRuleName(), rule2
											.getFormulaShow().replaceAll(
													"\r\n", "<br>"));
							child.add(rule2);
							children.add(ruleChart2);
						}
					}
				}
				if (child != null && child.size() > 0) {
					rule.setChild(child);
					ruleChart.setChildren(children);
					createTree(child, children);
				} else {
					logger.info(id + "的表达式未解析到其他引用项");
				}
			}
		}
	}

	/*** echart树结束 **/
	/*** 文件夹树开始 **/
	@RequestMapping(value = "/viewTree2")
	public String viewTree2(HttpServletRequest request,
			HttpServletResponse response, Model model) {
		String url = null;
		HashMap<String, Object> params = this.getParametersO(request);
		String erroMsg = "";
		try {
			String type = params.get("type") + "";
			if ("toJsp".equals(type)) {
				Integer id = Integer.valueOf(params.get("id") + "");
				RiskManageRule riskManageRule2 = riskManageRuleService
						.findById(id);
				model.addAttribute("rule", riskManageRule2);
				String tree = "";
				List<RiskManageRule> list = Arrays.asList(riskManageRule2);
				tree += createTree2(list);
				tree = tree.substring(4);
				tree = "<ul class='tree treeFolder expand'>" + tree;
				model.addAttribute("tree", tree);
				url = "risk/tree2";
			}
		} catch (Exception e) {
			logger.error("viewTree", e);
		}
		return url;
	}

	public String createTree2(List<RiskManageRule> list) {
		String tree = "<ul>";
		Map<String, RiskManageRule> map = SysCacheUtils.getAllRule();
		for (int j = 0; j < list.size(); j++) {
			RiskManageRule rule = list.get(j);
			String id = ConstantRisk.RULE_PREFIX + rule.getId();
			String title = rule.getFormulaShow().replaceAll("\r\n", "&#10;");
			if (rule.getRuleType().intValue() == RiskManageRule.RULE_BASE
					.intValue()) {
				tree += "<li><a title=\"默认值：" + title + "\">"
						+ ConstantRisk.RULE_PREFIX + rule.getId() + "-"
						+ rule.getRuleName() + "</a>";
			} else if (rule.getRuleType().intValue() == RiskManageRule.RULE_EXTEND
					.intValue()) {
				tree += "<li><a title=\"" + title + "\">"
						+ ConstantRisk.RULE_PREFIX + rule.getId() + "-"
						+ rule.getRuleName() + "</a>";
				String[] array = rule.getFormula().split(ConstantRisk.REGEX);
				List<RiskManageRule> child = new ArrayList<RiskManageRule>();
				List<String> hasCode = new ArrayList<String>();
				for (int i = 0; i < array.length; i++) {
					if (StringUtils.isNotBlank(array[i])) {
						String unit = array[i].trim();
						if (hasCode.contains(unit)) {
							continue;
						}
						hasCode.add(unit);
						RiskManageRule rule2 = map.get(unit);
						if (rule2 != null) {
							child.add(rule2);
						}
					}
				}
				if (child != null) {
					rule.setChild(child);
					tree += createTree2(child);
					tree += "</li>";
				} else {
					logger.info(id + "的表达式未解析到其他引用项");
				}
			}
		}
		return tree + "</li></ul>";
	}
	/*** 文件夹树结束 **/

}
